import ActionTypes from './utils/actionTypes'
// import isPlainObject from './utils/isPlainObject'

import * as data from "../../index";

export interface actionTypes{
    type:string;
    [key:string]:any;
}
export interface Reducer<S = stateType> {
    (state: S, actions: actionTypes): S
}
export type stateType = Object & {
    [key: string]: any;
    [key: number]: any;
}
export interface StoreCreate {
    (reducer: Reducer, preloadedState?: stateType | StoreEnhancer, enhancer?: StoreEnhancer): data.DataBase
}
export type StoreEnhancer = (next: StoreEnhancerStoreCreator) => StoreEnhancerStoreCreator;
export type StoreEnhancerStoreCreator = (reducer: Reducer, preloadedState?: stateType) => data.DataBase;


export function createStore(reducer: Reducer, preloadedState?: stateType | StoreEnhancer, enhancer?: StoreEnhancer): data.DataBase {
    // if (typeof preloadedState)
    if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
        enhancer = preloadedState
        preloadedState = undefined
    }
    if (typeof enhancer !== 'undefined') {
        return enhancer(createStore)(reducer, preloadedState)
    }

    class Store extends data.DataBase{
        public _name = "Store";
        protected state:stateType = (preloadedState as stateType)

        public async dispatch(actionTypes:actionTypes){
            let NewState:stateType = reducer(this.state,actionTypes)
            await this.evt.run(this.state,NewState,actionTypes);//接口，允许侵入性修改
            return (this.state = NewState)
        }
        public replaceReducer(nextReducer:Reducer){
            reducer = nextReducer
            this.dispatch({ type: ActionTypes.REPLACE })
        }
        public ["@@observable"](){
            return this
        }
    }

    let model = new Store();
    model.dispatch({ type: ActionTypes.INIT })
    return model
}
